package com.polukeuro.app.client.manager;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Widget;
import com.polukeuro.app.client.events.ConsummerHandler;
import com.polukeuro.app.client.events.ConsummerLoadDataEvent;
import com.polukeuro.app.client.events.ConsummerLoadErrorDataEvent;
import com.polukeuro.app.client.events.GlobalErrorEvent;
import com.polukeuro.app.client.events.GroupHandler;
import com.polukeuro.app.client.events.NextGroupEvent;
import com.polukeuro.app.client.events.NotYetImplementedEvent;
import com.polukeuro.app.client.events.NotYetImplementedHandler;
import com.polukeuro.app.client.events.PreviousGroupEvent;

public final class EventManager {

	private final static HandlerManager HM = new HandlerManager(
			EventManager.class);
	 
	private  static EventManager EM = null;

	private List<ConsummerHandler> cList;

	private List<GroupHandler> gList;
	
	private EventManagerHandler handler = new EventManagerHandler();

	// singleton
	private EventManager() {
		cList = new ArrayList<ConsummerHandler>();
		gList = new ArrayList<GroupHandler>();
		// register events handled by this manager only
		HM.addHandler(NotYetImplementedEvent.getType(), handler);
		// register all events handled by widgets
		HM.addHandler(ConsummerLoadDataEvent.getType(), handler);
		HM.addHandler(ConsummerLoadErrorDataEvent.getType(), handler);
		HM.addHandler(PreviousGroupEvent.getType(), handler);
		HM.addHandler(NextGroupEvent.getType(), handler);
	}

	public static EventManager getInstance() {
		if(EM == null) {
			EM = new EventManager();
		}
		return EM;
	} 
	
	public static HandlerManager getHandler() {
		return HM;
	}

	public void publish(GwtEvent<? extends EventHandler> event) {
		System.out.println("publish: " + event.getClass().toString()+" handled: " +HM.isEventHandled(event.getAssociatedType()));
		if(!HM.isEventHandled(event.getAssociatedType())) {
			HM.fireEvent(new NotYetImplementedEvent(event));
		}else {
			HM.fireEvent(event);
		}
	}

	/**
	 * Method called by the Factory to register a widgets
	 * 
	 * @param widget
	 */
	public void subscribe(Widget w) {
		if (w instanceof ConsummerHandler) {
			cList.add((ConsummerHandler) w);
		}

		if (w instanceof GroupHandler) {
			gList.add((GroupHandler) w);
		}
	}

	/**
	 * Method called by the Factory to unregister a widgets
	 * 
	 * @param widget
	 */
	public void unsubscribe(Widget w) {
		if (w instanceof ConsummerHandler) {
			cList.remove((ConsummerHandler) w);
		}

		if (w instanceof GroupHandler) {
			gList.remove((GroupHandler) w);
		}
	}
	
	private class EventManagerHandler implements ConsummerHandler, GroupHandler, NotYetImplementedHandler{
		public void loadData(ConsummerLoadDataEvent event) {
			for (ConsummerHandler w : cList) {
				w.loadData(event);
			}
		}

		public void loadErrorData(ConsummerLoadErrorDataEvent event) {
			for (ConsummerHandler w : cList) {
				w.loadErrorData(event);
			}
		}

		public void onNextGroupEvent(NextGroupEvent event) {
			for (GroupHandler w : gList) {
				w.onNextGroupEvent(event);
			}

		}

		public void onPreviousGroupEvent(PreviousGroupEvent event) {
			for (GroupHandler w : gList) {
				w.onPreviousGroupEvent(event);
			}
		}

		public void treatEvent(NotYetImplementedEvent event) {
			EventManager.this.publish(new GlobalErrorEvent(event.getWidget(), "Feature not yet implemented: " + event.getEventName()));
		}
	}

	

}
